#include <jni.h>
#include <string>
#include <iostream>
#include <cstring>

jobject createEngine(JNIEnv* env, const std::string& configJson) {
    std::cout << "Creating engine with config: " << configJson << std::endl;
    // 找到Engine类
    jclass engineClass = env->FindClass("com/gantang/poc/jni/so/Engine");
    if (engineClass == nullptr) {
        std::cerr << "Failed to find Engine class" << std::endl;
        return nullptr; // 处理错误情况，例如抛出Java异常
    }
    // 获取Engine类的构造函数
    jmethodID constructor = env->GetMethodID(engineClass, "<init>", "()V");
    if (constructor == nullptr) {
        std::cerr << "Failed to find Engine constructor" << std::endl;
        return nullptr; // 处理错误情况，例如抛出Java异常
    }
    // 创建Engine对象
    jobject engineObject = env->NewObject(engineClass, constructor);
    if (engineObject == nullptr) {
        std::cerr << "Failed to create Engine object" << std::endl;
    } else {
        std::cout << "Engine created successfully" << std::endl;
    }
    // 模拟申请100MB的JVM内存
    try {
        // 创建一个字节数组（byte array），每个元素占1字节
        jsize arraySize = 100 * 1024 * 1024; // 100MB
        jbyteArray byteArray = env->NewByteArray(arraySize);
        if (byteArray == nullptr) {
            std::cerr << "Failed to allocate 100MB JVM memory" << std::endl;
        } else {
            // 初始化数组
            jbyte* arrayElements = env->GetByteArrayElements(byteArray, nullptr);
            if (arrayElements != nullptr) {
                memset(arrayElements, 0, arraySize); // 初始化为0
                env->ReleaseByteArrayElements(byteArray, arrayElements, 0);
            }
            // 获取Engine类中的setMemoryBuffer方法
            jmethodID setMemoryBufferMethod = env->GetMethodID(engineClass, "setMemoryBuffer", "(Ljava/lang/Object;)V");

            if (setMemoryBufferMethod == nullptr) {
                std::cerr << "Failed to find setMemoryBuffer method" << std::endl;
            } else {
                // 调用setMemoryBuffer方法，将字节数组赋值给Engine对象的memoryBuffer字段
                env->CallVoidMethod(engineObject, setMemoryBufferMethod, byteArray);
            }
        }
    } catch (...) {
        std::cerr << "Exception occurred while allocating memory" << std::endl;
    }

    return engineObject;
}

jobject reloadEngine(JNIEnv* env, const std::string& engineId) {
    std::cout << "Reloading engine with ID: " << engineId << std::endl;

    // 重新加载引擎的逻辑
    jobject engine = createEngine(env, "{}"); // 假设重新加载后返回一个新的Engine实例
    if (engine == nullptr) {
        std::cerr << "Failed to reload engine" << std::endl;
    } else {
        std::cout << "Engine reloaded successfully" << std::endl;
    }

    return engine;
}

extern "C" {

    JNIEXPORT jobject JNICALL Java_com_gantang_poc_jni_so_EngineManage_nativeCreateEngine
       (JNIEnv *env, jobject obj, jstring configJson) {
        const char *nativeString = env->GetStringUTFChars(configJson, 0);
        jobject engine = createEngine(env, nativeString);
        env->ReleaseStringUTFChars(configJson, nativeString);
        return engine;
    }

    JNIEXPORT jobject JNICALL Java_com_gantang_poc_jni_so_EngineManage_nativeReloadEngine
       (JNIEnv *env, jobject obj, jstring engineId) {
        const char *nativeString = env->GetStringUTFChars(engineId, 0);
        jobject engine = reloadEngine(env, nativeString);
        env->ReleaseStringUTFChars(engineId, nativeString);
        return engine;
    }

    JNIEXPORT void JNICALL Java_com_gantang_poc_jni_so_Engine_nativeApi3
       (JNIEnv *env, jobject obj, jstring request) {
        const char *nativeString = env->GetStringUTFChars(request, 0);
        // 处理API3的业务逻辑
        std::cout << "nativeApi3 called with request: " << nativeString << std::endl;
        env->ReleaseStringUTFChars(request, nativeString);
    }

    JNIEXPORT void JNICALL Java_com_gantang_poc_jni_so_Engine_nativeApi4
       (JNIEnv *env, jobject obj, jstring request) {
        const char *nativeString = env->GetStringUTFChars(request, 0);
        // 处理API4的业务逻辑
        std::cout << "nativeApi4 called with request: " << nativeString << std::endl;
        env->ReleaseStringUTFChars(request, nativeString);
    }

    JNIEXPORT void JNICALL Java_com_gantang_poc_jni_so_Engine_nativeApi5
       (JNIEnv *env, jobject obj, jstring request) {
        const char *nativeString = env->GetStringUTFChars(request, 0);
        // 处理API5的业务逻辑
        std::cout << "nativeApi5 called with request: " << nativeString << std::endl;
        env->ReleaseStringUTFChars(request, nativeString);
    }

    JNIEXPORT void JNICALL Java_com_gantang_poc_jni_so_Engine_nativeApi6
       (JNIEnv *env, jobject obj, jstring request) {
        const char *nativeString = env->GetStringUTFChars(request, 0);
        // 处理API6的业务逻辑
        std::cout << "nativeApi6 called with request: " << nativeString << std::endl;
        env->ReleaseStringUTFChars(request, nativeString);
    }

    JNIEXPORT void JNICALL Java_com_gantang_poc_jni_so_Engine_nativeApi7
       (JNIEnv *env, jobject obj, jstring request) {
        const char *nativeString = env->GetStringUTFChars(request, 0);
        // 处理API7的业务逻辑
        std::cout << "nativeApi7 called with request: " << nativeString << std::endl;
        env->ReleaseStringUTFChars(request, nativeString);
    }

    JNIEXPORT void JNICALL Java_com_gantang_poc_jni_so_Engine_nativeDestroy
       (JNIEnv *env, jobject obj, jstring engineId) {
        const char *nativeString = env->GetStringUTFChars(engineId, 0);
        // 处理销毁引擎的业务逻辑
        std::cout << "nativeDestroy called with engineId: " << nativeString << std::endl;
        env->ReleaseStringUTFChars(engineId, nativeString);
    }

}
